#ifndef __RELEASE__H__
#define __RELEASE__H__

#include <httpclient.h>

class Property {
public:
    Property(){}
    Property(QString data) {
        auto split = data.indexOf(": ");
        // auto splits = data.left(split);
        m_key = data.mid(0, split).trimmed();
        m_value = data.mid(split+1).trimmed();
    }
    QString key() {
        return m_key;
    }
    QString value() {
        return m_value;
    }
private:
    QString m_key;
    QString m_value;
};

#define APT_PROPERTY_V(name, key) \
    Property name() { return get(#key); }

#define APT_PROPERTY(name)\
    APT_PROPERTY_V(name, name)

class AptRelease {
public:
    AptRelease (QString content, QString url = "") {
        auto end = content.indexOf("MD5Sum:\n");
        if (end != -1) {
            content = content.mid(0, end).trimmed();
        }
        if (url.isEmpty() == false) {
            content += "\nUrl: " + url;
        }
        m_content = content;
    }
    static AptRelease  fromUrl(QString url) {
        Request req(url);
        Response resp = HttpClient::instance().get(req);
        return AptRelease(resp.content(), url);
    };

    static QStringList keys() {
        return QStringList() << "Origin"
                             << "Label"
                             << "Suite"
                             << "Version"
                             << "Codename"
                             << "Changelogs"
                             << "Date"
                             << "Acquire"
                             << "Architectures"
                             << "Components"
                             << "Description"
                             << "Url";
    }

    QList<Property> properties() {
        QList<Property> properties;
        foreach (auto var, keys()) {
            auto p = get(var);
            if (p.key().isEmpty() == false) {
                properties << p;
            }
        }
        return properties;
    }

    APT_PROPERTY(Origin)
    APT_PROPERTY(Label)
    APT_PROPERTY(Suite)
    APT_PROPERTY(Version)
    APT_PROPERTY(Codename)
    APT_PROPERTY(Changelogs)
    APT_PROPERTY(Date)
    APT_PROPERTY(Acquire)
    APT_PROPERTY(Architectures)
    APT_PROPERTY(Components)
    APT_PROPERTY(Description)

    APT_PROPERTY(Url)

    QString content() {
        return m_content;
    }

private:
    Property get(QString key) {
#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
        for (auto &var : QString(m_content).split('\n', QString::SkipEmptyParts)) {
#else
        for (auto &var : QString(m_content).split('\n', Qt::SplitBehaviorFlags::SkipEmptyParts)) {
#endif
            if (var.startsWith(key)) {
                return Property(var);
            }
        }
        return Property();
    }

private:
    QString m_content;
};



class AptPackage {
public:
    AptPackage(QString content) {
        m_content = content.trimmed();
    }
    static QStringList keys() {
        return QStringList() << "Package"
                             << "Version"
                             << "Installed-Size"
                             << "Maintainer"
                             << "Architecture"
                             << "Depends"
                             << "Pre-Depends"
                             << "Description"
                             << "HomePage"
                             << "Tag"
                             << "Section"
                             << "Priority"
                             << "Size"
                             << "MD5sum"
                             << "FileName";
    }

    APT_PROPERTY(Package)
    APT_PROPERTY(Version)
    APT_PROPERTY_V(InstalledSize, Installed-Size)
    APT_PROPERTY(Maintainer)
    APT_PROPERTY(Architecture)
    APT_PROPERTY(Depends)
    APT_PROPERTY_V(PreDepends, Pre-Depends)
    APT_PROPERTY(Description)
    APT_PROPERTY(HomePage)
    APT_PROPERTY(Tag)
    APT_PROPERTY(Section)
    APT_PROPERTY(Priority)
    APT_PROPERTY(Size)
    APT_PROPERTY(MD5sum)
    APT_PROPERTY(Filename)

    QList<Property> properties() {
        QList<Property> properties;
        foreach (auto var, keys()) {
            auto p = get(var);
            if (p.key().isEmpty() == false) {
                properties << p;
            }
        }
        return properties;
    }
    QString content() {
        return m_content;
    }
private:
    Property get(QString key) {
#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
        for (auto &var : QString(m_content).split('\n', QString::SkipEmptyParts)) {
#else
        for (auto &var : QString(m_content).split('\n', Qt::SplitBehaviorFlags::SkipEmptyParts)) {
#endif
            if (var.startsWith(key)) {
                return Property(var);
            }
        }
        return Property();
    }

private:
    QString m_content;
};

#endif  //!__RELEASE__H__
